/*
 * Copyright (C) 2014 Steven Kurilovitch
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */

package com.goodjaerb.swccg.core;

import java.util.EnumMap;
import java.util.List;

/**
 *
 * @author Steven Kurilovitch
 */
public final class CardData implements Comparable<CardData> {
    
    private final EnumMap<Field, String> map;
    
    private final Side side;
    private final Type type;
    private List<Icon> icons;
        
    private String imagePath;
    private boolean twoSided;
    private String backImagePath;
    
    private boolean isFront;
    
    public CardData(Side s, Type t) {
        this.side = s;
        this.type = t;
        this.twoSided = false;
        this.isFront = true;
        
        map = new EnumMap<>(Field.class);
        map.put(CardData.Field.SIDE, side.toString());
        map.put(CardData.Field.TYPE, type.toString());
    }
    
    public CardData(CardData cd) {
        this(cd.getSide(), cd.getType());
        
        for(Field f : Field.values()) {
            this.set(f, cd.get(f));
        }
        
        this.setTwoSided(cd.isTwoSided());
        this.setIcons(cd.getIcons());
        this.setImagePath(cd.getImagePath());
        this.setBackImagePath(cd.getBackImagePath());
    }
    
    public void set(Field f, String v) {
        map.put(f, v);
    }
    
    public String get(Field f) {
        return map.get(f);
    }
    
    public boolean isLegacy() {
        String holoPath = get(Field.HOLOTABLE_CARD_PATH);
        return holoPath.startsWith("card \"/legacy/") || holoPath.startsWith("card \"/TWOSIDED/legacy/");
    }

    public Side getSide() {
        return side;
    }

    public Type getType() {
        return type;
    }

    public boolean isTwoSided() {
        return twoSided;
    }

    public void setTwoSided(boolean twoSided) {
        this.twoSided = twoSided;
    }
    
    public boolean isFront() {
        return isFront;
    }
    
    public void setIsFront(boolean b) {
        isFront = b;
    }
    
    // Didn't really handle two-sided cards the best way originally so to fix
    // a small navigation issue I do this to create separate objects for each
    // side of a card.
    public CardData getAsBack() {
        CardData cd = new CardData(this);
        cd.setIsFront(false);
        return cd;
    }

    public List<Icon> getIcons() {
        return icons;
    }

    public void setIcons(List<Icon> icons) {
        this.icons = icons;
    }

    public boolean isLocation() {
        return type.name().contains("LOCATION");
    }
    
    public String getImagePath() {
        return imagePath;
    }
    
    public void setImagePath(String s) {
        this.imagePath = s;        
    }
    
    public String getBackImagePath() {
        return backImagePath;
    }

    public void setBackImagePath(String backImagePath) {
        this.backImagePath = backImagePath;
    }
    
    @Override
    public boolean equals(Object o) {
        if(o instanceof CardData) {
            CardData other = (CardData)o;
            return get(Field.HOLOTABLE_CARD_PATH).equals(other.get(Field.HOLOTABLE_CARD_PATH)) && isFront() == other.isFront();
        }
        return false;
    }

    @Override
    public String toString() {
        String s = get(Field.TITLE);
        if(isTwoSided()) {
            s += isFront() ? " (FRONT)" : " (BACK)";
        }
        return s;
    }
    
    public String getStringData() {
        return "CardData{" + "map=" + map + ", side=" + side + ", type=" + type + ", icons=" + icons + ", imagePath=" + imagePath + ", twoSided=" + twoSided + ", backImagePath=" + backImagePath + '}';
    }
    
    @Override
    public int compareTo(CardData cd) {
        if(this.getSide().equals(cd.getSide())) {
            if(this.getType().equals(cd.getType())) {
                return this.get(Field.NAME).compareTo(cd.get(Field.NAME));
            }
            return this.getType().compareTo(cd.getType());
        }
        return this.getSide().compareTo(cd.getSide());
    }
    
    static public enum Side {
        LIGHT, DARK
    }
    
    static public enum Type {
        ADMIRALS_ORDER("Admiral's Order"), 
        CHARACTER_ALIEN("Character - Alien"), 
        CHARACTER_ALIEN_REBEL("Character - Alien/Rebel"), 
        CHARACTER_ALIEN_REPUBLIC("Character - Alien/Republic"), 
        CHARACTER_ALIEN_IMPERIAL("Character - Alien/Imperial"), 
        CHARACTER_DARK_JEDI_MASTER("Character - Dark Jedi Master"), 
        CHARACTER_DARK_JEDI_MASTER_IMPERIAL("Character - Dark Jedi Master/Imperial"), 
        CHARACTER_DROID("Character - Droid"), 
        CHARACTER_IMPERIAL("Character - Imperial"), 
        CHARACTER_JEDI_MASTER("Character - Jedi Master"), 
        CHARACTER_NEW_REPUBLIC("Character - New Republic"), 
        CHARACTER_REBEL("Character - Rebel"), 
        CHARACTER_REBEL_REPUBLIC("Character - Rebel/Republic"), 
        CHARACTER_REPUBLIC("Character - Republic"), 
        CHARACTER_REPUBLIC_IMPERIAL("Character - Republic/Imperial"), 
        CHARACTER_SITH("Character - Sith"), 
        CREATURE("Creature"), 
        DEFENSIVE_SHIELD("Defensive Shield"), 
        DEVICE("Device"), 
        EFFECT("Effect"), 
        EFFECT_IMMEDIATE("Effect - Immediate"), 
        EFFECT_MOBILE("Effect - Mobile"), 
        EFFECT_POLITICAL("Effect - Political"), 
        EFFECT_STARTING("Effect - Starting"), 
        EFFECT_UTINNI("Effect - Utinni"), 
        EPIC_EVENT("Epic Event"), 
        GAME_AID("Game Aid"), 
        INTERRUPT_LOST("Interrupt - Lost"), 
        INTERRUPT_LOST_OR_STARTING("Interrupt - Lost or Starting"), 
        INTERRUPT_STARTING("Interrupt - Starting"), 
        INTERRUPT_USED("Interrupt - Used"), 
        INTERRUPT_USED_OR_LOST("Interrupt - Used or Lost"), 
        INTERRUPT_USED_OR_STARTING("Interrupt - Used or Starting"), 
        JEDI_TEST("Jedi Test"), 
        LOCATION_SECTOR("Location - Sector"), 
        LOCATION_SITE("Location - Site"), 
        LOCATION_SYSTEM("Location - System"), 
        MISSION("Mission"), 
        OBJECTIVE("Objective"), 
        PODRACER("Podracer"), 
        STARSHIP_CAPITAL("Starship - Capital"), 
        STARSHIP_SQUADRON("Starship - Squadron"), 
        STARSHIP_STARFIGHTER("Starship - Starfighter"), 
        VEHICLE_COMBAT("Vehicle - Combat"), 
        VEHICLE_CREATURE("Vehicle - Creature"), 
        VEHICLE_SHUTTLE("Vehicle - Shuttle"), 
        VEHICLE_TRANSPORT("Vehicle - Transport"), 
        WEAPON_ARTILLERY("Weapon - Artillery"), 
        WEAPON_AUTOMATED("Weapon - Automated"), 
        WEAPON_CHARACTER("Weapon - Character"), 
        WEAPON_DEATH_STAR("Weapon - Death Star"), 
        WEAPON_DEATH_STAR_II("Weapon - Death Star II"), 
        WEAPON_STARSHIP("Weapon - Starship"), 
        WEAPON_VEHICLE("Weapon - Vehicle");
        
        private final String displayString;
        
        Type(String displayString) {
            this.displayString = displayString;
        }
        
        @Override
        public String toString() {
            return displayString;
        }
    }
    
    static public enum Icon {
        PERMANENT_WEAPON, PERMANENT_PILOT, PILOT, PRESENCE, SIDIOUS, VADER, WARRIOR, CAVE, CREATURE, EXTERIOR, INTERIOR, MOBILE, PLANET, SPACE, STARSHIP, STARSHIP_SITE, SYSTEM, UNDERGROUND, UNDERWATER, VEHICLE, VEHICLE_SITE, CLONE_ARMY, GRABBER, INDEPENDENT, NAV_COMPUTER, PRESENCE_ICON, REPUBLIC, SCOMP_LINK, SCOUNDREL, SELECTIVE_CREATURE, SEPARATIST, SETUP, TRADE_FEDERATION, A_NEW_HOPE, CLOUD_CITY, CORUSCANT, DAGOBAH, DEATH_STAR_II, ENDOR, EPISODE_I, HOTH, JABBAS_PALACE, PREMIUM, REFLECTIONS_II, REFLECTIONS_III, SPECIAL_EDITION, TATOOINE, THEED_PALACE
    }
    
    static public enum Field {
        TITLE, NAME, 
        SET, RARITY, 
        SIDE, TYPE, 
        DESTINY, POWER, ABILITY, DEFENSE_LABEL, DEFENSE, SUBTYPE, CHARACTER_SUBTYPE, VEHICLE_SUBTYPE, SQUADRON_SUBTYPE, CAPITAL_SUBTYPE, STARFIGHTER_SUBTYPE, POLITICS, DEPLOY, FORFEIT, SPEED_LABEL, SPEED, PARSEC,
        LORE, TEXT,
        LIGHT_FORCE, LIGHT_TEXT, DARK_FORCE, DARK_TEXT, 
        HOLOTABLE_CARD_PATH;
    }
}
